//
//  CountDownModeCrushView.h
//  FruitCrush
//
//  Created by gaoyu on 15/7/19.
//
//

#ifndef __FruitCrush__CountDownModeCrushView__
#define __FruitCrush__CountDownModeCrushView__

#include "cocos2d.h"
USING_NS_CC;

#define CRUSH_VIEW_WIDTH   320
#define CRUSH_VIEW_HEIGHT  225

typedef std::function<void(Ref*)> CountDownModeCrushViewCallback;
typedef std::function<void(Ref*)> CountDownModeCrushViewBadStateCallback;
typedef std::function<void(Ref*)> CountDownModeCrushViewUpdateCallback;

class CrushUnitSprite;
class BadStateUnitSprite;

class CountDownModeCrushView : public cocos2d::Layer
{
public:
	CC_SYNTHESIZE(int, m_bombNum, BombNum);
    CountDownModeCrushView();
    ~CountDownModeCrushView();
    CREATE_FUNC(CountDownModeCrushView);
    virtual bool init() override;
    virtual void update(float dt) override;
    virtual bool onTouchBegan(Touch *touch, Event *unused) override;
    virtual void onTouchMoved(Touch *touch, Event *unused) override;
    void setCallback(const CountDownModeCrushViewCallback& callback);
    void setUpdateCallback(const CountDownModeCrushViewUpdateCallback& callback);
    void setBadCallback(const CountDownModeCrushViewBadStateCallback& callback);
    CC_SYNTHESIZE_READONLY(int, m_crushType, CrushType);
    CC_SYNTHESIZE_READONLY(int, m_suckNum, SuckNum);
    CC_SYNTHESIZE_READONLY(int, m_combosNum, CombosNum);
    void setPause(bool pause);
    void initMatrixBad(bool* data);
    void initMatrixBadUp(bool* data);
    void initMatrix(bool* data);
    void bossCreateJellys();
    void initMatrixBlank(bool* data);
    void setTypeNumLimit(int num);
    int getBadStateNum();

protected:
    // callback
    CountDownModeCrushViewCallback _callback;
    CountDownModeCrushViewBadStateCallback _badCallback;
    CountDownModeCrushViewUpdateCallback _updateCallback;
private:
    SpriteBatchNode *spriteSheet;
    CrushUnitSprite **m_matrix;
    int m_width;
    int m_height;
    // for rapid count position
    float m_matrixLeftBottomX;
    float m_matrixLeftBottomY;
    bool m_isTouchEnable;// is need to deal with touch event
    CrushUnitSprite *m_srcSushi;
    CrushUnitSprite *m_destSushi;
    bool m_isAnimationing;
    bool m_isNeedFillVacancies;
    bool m_movingVertical;
    bool m_isPause;
    float m_badStateLastTime;
    //add for bad state
    SpriteBatchNode *spriteSheetBad;
    BadStateUnitSprite **m_matrix_bad;
    SpriteBatchNode *spriteSheetBadUp;
    BadStateUnitSprite **m_matrix_bad_up;
    bool m_needCreateJelly;
    SpriteBatchNode *spriteSheetBlank;
    BadStateUnitSprite **m_matrix_blank;
    int typeNumLimit;

    
    //void initMatrix();
    void createAndDropSushi(int row, int col);
    Point positionOfItem(int row, int col);
    bool checkAndRemoveChain();
    void getColChain(CrushUnitSprite *sushi, std::list<CrushUnitSprite *> &chainList);
    void getRowChain(CrushUnitSprite *sushi, std::list<CrushUnitSprite *> &chainList);
    bool removeSushi();
    void actionEndCallback(Node *node);
    void explodeSushi(CrushUnitSprite *sushi);
    void fillVacancies();
    CrushUnitSprite *sushiOfPoint(Point *point);
    bool swapSushi();
    void markRemove(CrushUnitSprite *sushi);
    void explodeSpecialH(Point point);
    void explodeSpecialV(Point point);
    //add
    Vec2 touchLocationFix(Vec2 location);
    void createBadState(int row, int col);

    void createBadUpState(int row, int col);
    bool isHandByMonster(int row, int col);
    void createJelly(int row, int col);
    void checkJellyEatUnit();
    __Array* getAllCanEatJelly();
    bool isJellyHasEatTarget(int row, int col);
    void JellyEatTarget(int row, int col);
    void jellyEatEndCallback(Node *node);
    void explodeJelly(int row,int col);
    void crushJellyCheck(int row, int col);
    void bossCreateJelly(int row, int col);
    void createAndDropBomb(int row, int col);
    bool isThereHasBomb();
    void createBlank(int row, int col);
       int getBlankNum(int newRow, int col,int row);
	bool bombCreateCheck(int row, int col);
};

#endif /* defined(__FruitCrush__CountDownModeCrushView__) */
